.TITLE DREIF .IDENT /17.04/ ; ; Copyright (c) 1995-1999 by Mentec Inc., U.S.A. ; All rights reserved. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; D. N. CUTLER 13-SEP-73 ; ; ; MODIFIED FOR RSX-11M-PLUS VERSION 3.0 BY: ; ; J. W. BERZLE ; J. R. KAUFFMAN ; J. M. LAWLER ; B. S. MCCARTHY ; L. B. MCCULLEY ; ; MODIFIED FOR RSX-11M-PLUS V4.0 BY: ; ; B. S. MCCARTHY ; L. M. ZIEGLER ; K. L. NOEL ; ; MODIFIED FOR RSX-11M-PLUS V4.1 BY: ; ; K. L. NOEL ; P. K. M. WEISS ; Eric Postpischil ; L. B. McCulley ; ; MODIFIED FOR RSX-11M-PLUS V4.2 BY: ; ; P. K. M. WEISS ; L. M. PETERSON ; ; MODIFIED FOR RSX-11M-PLUS V4.3 BY: ; ; K. L. NOEL ; ; MODIFIED FOR RSX-11M-PLUS V4.5 BY: ; ; D. CARROLL 15-Feb-1993 17.03 ; ; DC101 -- CORRECT KERNEL AST DISPATCH ON MP SYSTEMS ; DURING EXIT PROCESSING (THEY CAN HAPPEN) ; ; D. Carroll 05-Jan-1995 17.04 ; ; DC350 -- Allow CP/RSX to return exit status back out to ; to the VMS parent process ; ; ; EXIT DIRECTIVES ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$,HDRDF$,PCBDF$,PKTDF$,TCBDF$,BGCK$A .MCALL CPRDF$ CPRDF$ ABODF$ ;DEFINE TASK ABORT CODES HDRDF$ ;DEFINE TASK HEADER OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS .IF DF A$$CNT .MCALL ACNDF$ ACNDF$ ;DEFINE ACCOUNTING BLOCK OFFSETS .ENDC .IF DF L$$GCL .MCALL LNMDF$ LNMDF$ .ENDC ; ; LOCAL SYMBOL DEFINITION ; CLRMSK=T2.AST!T2.DST!T2.SEF!T2.HLT!T2.ABO!T2.REX CLRMSK=CLRMSK!<*2>!T2.STP!T2.SPN!T2.WFR MAP6=140000 ;APR 6 ;+ ; **-$DREIF-EXIT IF ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO TERMINATE THE EXECUTION OF THE ; ISSUING TASK IF, AND ONLY IF, AN INDICATED EVENT FLAG IS CLEAR. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(53.),DPB SIZE(2.). ; WD. 01 -- EVENT FLAG NUMBER OF EVENT FLAG THAT MUST BE CLEAR. ; ; INPUTS: ; ; R0=EVENT FLAG MASK WORD. ; R1=EVENT FLAG MASK ADDRESS. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF 'D.RS22' IS RETURNED IF THE SPECIFIED ; EVENT FLAG IS SET. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS97' IF NO OR AN INVALID EVENT ; FLAG NUMBER IS SPECIFIED. ;- .ENABL LSB .IF NDF D$$PAR $DREIF::BIT R0,(R1) ;EVENT FLAG CLEAR? BEQ $DREXT ;IF EQ YES DRSTS D.RS22 ;SET DIRECTIVE STATUS ;+ ; **-$DREXT-EXIT ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO TERMINATE THE EXECUTION OF THE ; ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(51.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; NOTE: THIS DIRECTIVE IS ALSO CALLED FROM THE DISPATCHER AND ; THEREFORE ONLY REQUIRES R5 TO BE LOADED ON ENTRANCE. ; ; PRIVILEGED TASKS WHICH DESIRE TO CALL $DREXT DIRECTLY ; SHOULD SWITCH TO SYSTEM STATE AND IMMEDIATELY CALL $DREXT ; WITHOUT CALLING ANY OTHER EXEC SUBROUTINES. ; THIS IS BECAUSE OF POSSIBLE SIDE EFFECTS OF ; OTHER EXEC ROUTINES (SUCH AS $TSKRP). ; ; BECAUSE MANY PRIVILEGED TASKS CALL $DREXT, WE ; WILL UNCONDITIONALLY MAP THE TASK HEADER SO THAT ; THIS CODE DOES NOT HAVE TO BE ADDED ELSEWHERE. ; ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; NO STATUS IS RETURNED TO THE ISSUING TASK SINCE THIS DIRECTIVE ; TERMINATES ITS EXECUTION. ;- $DREXT:: ;REFERENCE LABEL .IF DF X$$HDR MOV $SAHDB,KISAR6 ;MAP CURRENT TASK HEADER .ENDC ; DF X$$HDR .IF DF P$$OFF BIT #T3.ACP,T.ST3(R5) ;IS TASK AN ACP? BNE $DREX1 ;IF NE YES MOV #EX$SUC,T.EFLG+2(R5) ;SET SUCCESSFUL EXIT STATUS $DREX2::MOV #S.CEXT,T.EFLG(R5) ;SET SUCCESS CODE IN ABORT CODE .ENDC $DREX1:: .IFF ; NDF D$$PAR $DREX3:: ;REFERENCE LABEL FOR STUB ROUTINE ;IN DRSUB .IF DF K$$DAS MOV KINAR5,KDSAR5 ;REMAP IN D SPACE (IN CASE CALLED FROM ;SCHEDULER) .ENDC ; DF K$$DAS .ENDC ; NDF D$$PAR .IF DF, G$$GEF BIT #T2.AST,T.ST2(R5) ;TASK IN AST STATE? BEQ 56$ ;IF EQ NO BIT #T2.WFR*2,T.ST2(R5) ;WAS TASK IN AST WFR? BEQ 56$ ;IF EQ NO MOV H.EFSV(R4),R3 ;GET EVENT FLAG MASK ADDRESS CALL $DEAGF ;DEACCESS GROUP GLOBAL EVENT FLAGS 56$: MOV $SAHPT,R4 ;GET ADDRESS OF TASK HEADER CALL $UNLCK ;UNLOCK GROUP GLOBAL EVENT FLAGS BCS 57$ ;IF CS ALREADY UNLOCKED CALL $ELIM ;ELIMINATE THEM IF NECESSARY 57$: MOV $TKTCB,R5 ;RESTORE TCB POINTER .ENDC ; DF G$$GEF CALL $DRCMT ;CANCEL MARK TIME REQUESTS .IF DF D$$MND CMP $TKTCB,$DITCB ;IS DIAMOND WATCHING THIS TASK? BNE 101$ ;IF NE NO BIC #1,@$DICSR ;RESET DIAMOND REGISTER CLR $DITCB ;CLEAR TCB ADDRESS 101$: ;REFERENCE SYMBOL .ENDC .IF DF C$$INT MOV T.PCB(R5),R4 ;POINT TO TASK PCB BIT #PS.CHK,P.STAT(R4) ;DOES TASK POSSIBLY HAVE ANY ITB'S? BEQ 2$ ;IF EQ NO 1$: MOV P.DPCB(R4),R1 ;PICK UP NEXT ITB POINTER BEQ 2$ ;IF EQ NONE LEFT .IF DF D$$PAR MOV #$DISIN,-(SP) ;PUSH ADDRESS OF DISABLE ROUTINE CALL $MPDC2 ;CALL THROUGH INDIRECT ROUTINE .IFF ; DF D$$PAR CALL $DISIN ;DISCONNECT INTERRUPT VECTOR .ENDC ; DF D$$PAR BR 1$ ; 2$: ;REF LABEL .ENDC .IF DF M$$PRO CLR T.RRM(R5) ;REMOVE ALL CPU AFFINITY .ENDC .IF DF D$$PAR MOV $DRAPR,KINAR5 ;MAP THE DIRECTIVE PARTITION .ENDC CALL $RLMCB ;RELEASE MCR COMMAND BUFFER CMP R5,$LSTLK ;TASK OWN MCR DATA BASE LOCK? BNE 3$ ;IF NE NO CLR $LSTLK ;CLEAR OWNER TCB ADDRESS 3$: BIS #T2.HLT,T.ST2(R5) ;SET TO HALT TASK CLRB $CXDBL ;CLEAR CONTEXT DISABLE FLAG MOV T.SAST(R5),R0 ;GET ADDRESS OF SPECIFIED AST BLOCK BEQ 5$ ;IF EQ LIST IS EMPTY MOV R0,@T.ASTL+2(R5) ;MOVE SPECIFIED AST LIST TO AST LIST 4$: MOV R0,R1 ;COPY ADDRESS OF SPECIFIED AST BLOCK MOV (R0),R0 ;GET ADDRESS OF NEXT BLOCK BNE 4$ ;IF NE THERE ARE MORE IN THE LIST MOV R1,T.ASTL+2(R5) ;SET LIST TAIL CLR T.SAST(R5) ;ASTS NO LONGER SPECIFIED 5$: JSR R5,MTQUE ;EMPTY AST QUEUE .WORD T.ASTL ;OFFSET TO AST QUEUE LISTHEAD .WORD $DEACB ;ADDRESS OF DEALLOCATION ROUTINE BIT #T3.NSD!T3.ACP,T.ST3(R5) ;FLUSH RECEIVE QUEUE? BNE 7$ ;IF NE NO .IF DF P$$OOL CALL MTRCVL ;EMPTY RECEIVE LIST .IFF JSR R5,MTQUE ;EMPTY RECEIVE QUEUE .WORD T.RCVL ;OFFSET TO RECEIVE QUEUE LISTHEAD .WORD $DEPKT ;ADDRESS OF DEALLOCATION ROUTINE .ENDC 7$: ;REF LABEL .IF DF X$$HDR MOV $SAHPT,R4 ;GET CURRENT TASK HEADER ADDRESS .IFF MOV $HEADR,R4 ;GET CURRENT TASK HEADER ADDRESS .ENDC .IF DF P$$LAS BIT #T3.REM,T.ST3(R5) ;REMOVE ON EXIT ? BNE 71$ ;IF NE, YES - $REMOV WILL HANDLE THIS CASE MOV R5,R0 ;COPY TCB ADDRESS CALL $CLSRF ;REMOVE IT FROM ALL RREF PACKETS 71$: ;REFERENCE LABEL JSR R5,MTQUE ;EMPTY RECEIVE BY REFERENCE QUEUE .WORD T.RRFL ;OFFSET TO RECEIVE BY REF LISTHEAD .WORD $DEPKT ;ADDRESS OF DEALLOCATION ROUTINE .ENDC 8$: MOV #SCNLN,-(SP) ;SET ADDRESS OF LUT SCANNING CO-ROUTINE TSTB T.IOC(R5) ;ANY I/O OUTSTANDING? BNE 9$ ;IF NE YES TSTB T.TIO(R5) ;TASK HAVE OUTSTANDING BUFFERED I/O BEQ 30$ ;IF EQ NO 9$: .IF DF C$$RTK ;IF REMOTE TASK BIT #F5.RTK,$FMSK5 ;ARE REMOTE TASKS BEING USED BEQ 99$ ;IF EQ NO ; ; ALLOCATE A PACKET FOR THE GENERIC DRIVER TO USE TO KILL I/O WITH ; CLR $CPPKT ;ASSUME NO PACKET CLR $CPLUN ;INDICATE ALL I/O TO BE KILLED TSTB T.TKI(R5) ;TASK HAD ANY CONTACT WITH HOST? BEQ 99$ ;IF EQ NO, NO NEED TO ALLOCATE CPRBUF MOV #AL$SWS,R0 ;INDICATE THAT WE ARE CALLING FROM SYSTEM STATE MOV #1,R1 ;GET JUST ONE BLOCK CALL $CPALO ;ALLOCATE A PACKET BCC 92$ ;IF CC - ALLOCATION SUCCEEDED CLR R0 ;INDICATE NO PACKET 92$: MOV R0,$CPPKT ;SAVE PACKET ADDRESS FOR GENERIC DRIVER .ENDC ;C$$RTK 99$: BIT #T2.ABO,T.ST2(R5) ;TASK ALREADY MARKED FOR ABORT BNE 10$ ;IF NE YES MOV #S.IOMG,R0 ;SET REASON FOR ABORT CALL $ABCTK ;ABORT CURRENT TASK 10$: MOV (SP),-(SP) ;DUPLICATE ADDRESS OF LUT SCANNING CO-ROUTINE 20$: CALL @(SP)+ ;GET NEXT ASSIGNED LUN BCS 30$ ;IF CS END OF LOGICAL UNIT TABLE CALL $IOKIL ;KILL I/O ON UNIT FOR CURRENT TASK BR 20$ ;GO AGAIN 30$: .IF DF C$$RTK BIT #F5.RTK,$FMSK5 ;ARE REMOTE TASKS BEING USED? BEQ 35$ ;IF EQ NO MOV $CPPKT,R0 ;GET ADDRESS OF CPRBUF PACKET BEQ 35$ ;IF NONE, IT WAS ALREADY DEALLOCATED CALL $CPDEA ;OTHERWISE, DEALLOCATE IT NOW .ENDC ;C$$RTK 35$: CALL @(SP)+ ;GET NEXT ASSIGNED LUN BCS 100$ ;IF CS END OF LOGICAL UNIT TABLE .IF DF M$$NET&T$$LTH CALL LTPRE ;TELL LAT PROCESS IF NECESSARY .ENDC ; DF M$$NET&T$$LTH CMP $TKTCB,U.ATT(R5) ;UNIT ATTACHED TO CURRENT TASK? BNE 40$ ;IF NE NO MOV #IO.DET,R4 ;SET DETACH I/O FUNCTION BR 50$ ; 40$: MOV (R1),R2 ;FILE OPEN ON UNIT? BEQ 30$ ;IF EQ NO ASR R2 ;ACCESS OR DEACCESS PENDING? BCS 30$ ;IF CS YES ASL R2 ;RESTORE WINDOW BLOCK ADDRESS (INTERLOCK CLRD) BIT $WCFLG,U.CW1(R5) ;DEVICE FILES-11? BEQ 45$ ;IF EQ NO, ALWAYS DEACCESS TSTB W.IOC(R2) ;I/O IN PROGRESS THROUGH WINDOW BLOCK? BNE 30$ ;IF NE YES, DON'T DEACCESS 45$: MOV #IO.CLN,R4 ;SET CLOSE LUN I/O FUNCTION 50$: CMP (SP)+,(SP)+ ;CLEAN STACK MOV R1,-(SP) ;SAVE ADDRESS OF SECOND LUN WORD MOV #I.LGTH,R1 ;SET LENGTH OF BLOCK NEEDED CALL $ALOCB ;ALLOCATE I/O PACKET MOV (SP)+,R3 ;RETRIEVE ADDRESS OF SECOND LUN WORD BCS TKWSE ;IF CS NO CORE AVAILABLE MOV R0,R1 ;COPY ADDRESS OF I/O PACKET TST (R0)+ ;POINT TO SECOND WORD MOV $TKTCB,R2 ;GET ADDRESS OF TCB OF CURRENT TASK MOVB T.IOC(R2),-(SP) ;SAVE CURRENT I/O COUNT INCB T.IOC(R2) ;INCREMENT OUTSTANDING I/O COUNT MOVB T.PRI(R2),(R0)+ ;SET REQUEST PRIORITY CLRB (R0)+ ;CLEAR EVENT FLAG NUMBER MOV R2,(R0)+ ;INSERT CURRENT TASK TCB ADDRESS MOV R3,(R0)+ ;INSERT ADDRESS OF SECOND LUN WORD MOV R5,(R0)+ ;INSERT UCB ADDRESS MOV R4,(R0)+ ;INSERT I/O FUNCTION CODE MOV #/2,-(SP) ; WORDS REMAINING IN I/O PACKET 55$: CLR (R0)+ ; CLEAR REMAINDER OF I/O PACKET DEC (SP) ; DONE? BNE 55$ ; IF NE NO MOV #$DRQRQ,(SP) ; ASSUME QUEUE TO DRIVER CMP #IO.CLN,R4 ; CLOSE LUN I/O FUNCTION? BNE 70$ ; IF NE NO MOV (R3),R4 ; GET WINDOW ADDRESS INC (R3) ; INTERLOCK LUN MOV U.VCB(R5),R3 ; GET VCB ADDRESS, REALLY ONE? BEQ 60$ ; IF EQ NO INC (R3) ; INCREMENT VOLUME TRANSACTION COUNT BIT #DV.F11,U.CW1(R5) ; FILES-11 DEVICE? BEQ 60$ ; IF EQ NO INCB W.IOC(R4) ; INCREMENT WINDOW I/O COUNT ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT NUMBER 21. ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- $SPH21==. ;SPM CHANGES THE INSTRUCTION AT ;THE LOCATION OF THIS LABEL MOV U.ACP(R5),R0 ; SET ACP TCB MOV #$EXRQP,(SP) ; QUEUE DIRECTLY TO ACP 60$: BISB #200,I.EFN(R1) ; SET VIRTUAL I/O FLAG MOV T.ATT(R2),R3 ; GET FIRST ATTACHMENT DESCRIPTOR INCB A.IOC-A.TCBL(R3) ; LOCK DOWN HEADER MOV A.PCB-A.TCBL(R3),R3 ; POINT TO TASK REGION PCB INCB P.IOC(R3) ; LOCK REGION BY INC'ING I/O COUNT 70$: .IF DF C$$RTK BIT #F5.RTK,$FMSK5 ;ARE REMOTE TASKS BEING USED? BEQ 72$ ;IF EQ NO CMP (R5),$XXLOW ;IS THIS A GENERIC DEVICE? BLO 72$ ;IF LO NO CMP (R5),$XXHGH ;GENERIC DEVICE? BHI 72$ ;IF HI NO INC I.FCN(R1) ;SET BIT TO TELL XX DRIVER WE ARE COMING FROM ; DREIF 72$: .ENDC ;C$$RTK CALL @(SP)+ ;QUEUE THE PACKET SOMEWHERE .IF DF X$$HDR MOV $SAHDB,KISAR6 ; RESTORE MAPPING .ENDC MOV $TKTCB,R5 ;GET ADDRESS OF TCB OF CURRENT TASK CMPB T.IOC(R5),(SP)+ ;REQUEST ALREADY FINISHED? BHI 80$ ;IF HI NO JMP 8$ ; 80$: MOV T.ASTL(R5),R0 ;GET ADDRESS OF FIRST AST BLOCK BEQ 85$ ;IF EQ THERE IS NONE TSTB A.CBL(R0) ;KERNEL AST ? BMI TKWSE ;IF MI YES, RUNDOWN BIT MIGHT DEADLOCK 85$: BIS #TS.RDN,T.STAT(R5) ;SET I/O RUNDOWN IN PROGRESS TKWSE: CALLR $TKWSE ;WAITFOR SIGNIFICANT EVENT 100$: TSTB T.IOC(R5) ;ANY I/O STILL OUTSTANDING? BNE 80$ ;IF NE YES TSTB T.TIO(R5) ;TASK HAVE OUTSTANDING BUFFERED I/O BNE 80$ ;IF NE YES .DSABL LSB RNDWN: ;PARENT/OFFSPRING-RELATED RUNDOWN .IF DF C$$RTK BIT #F5.RTK,$FMSK5 ; ARE REMOTE TASKS BEING USED? BEQ 16$ ; NO, SKIP DETACH SUPPORT. ; THE AME WILL AUTOMATICALLY PERFORM DETACHES ; IN ITS OWN DATA STRUCTURES WHEN IT SEES ; TASK TERMINATION. WE SUPPORT THIS BY ; DELETING THE ACBS ON THE RSX SIDE. MOV #SCNLN,-(SP) ; SET UP LUN-SCANNING CO-ROUTINE. 10$: CALL @(SP)+ ; GET NEXT ACTIVE LUN. BCS 16$ ; THERE IS NONE; WE ARE DONE. MOV R5,R3 ; COPY UCB ADDRESS. MOV (R3),R0 ; GET DCB ADDRESS CMP D.NAM(R0),#"HT ; IS THIS AN HT? BEQ 11$ ; IF EQ YES CMP D.NAM(R0),#"NS ; IS THIS AN NS? BNE 10$ ; IF NE NO, NO U.RAST FIELD 11$: ADD #U.RAST,R3 ; POINT TO ACB QUEUE. MOV R3,R0 ; COPY POINTER; KEEP HEADER POINTER. 12$: MOV R0,R2 ; COPY POINTER. MOV (R2),R0 ; GET NEXT ACB. BEQ 10$ ; THERE IS NONE; GO TO NEXT LUN. CMP A.PRM+14(R0),$TKTCB ; IS ACB FOR TERMINATING TASK? BNE 12$ ; NO, CHECK NEXT ACB. MOV (R0),(R2) ; MAKE PREVIOUS ACB POINT TO NEXT ACB. BNE 13$ ; THERE IS A NEXT ACB, SO LEAVE TAIL ALONE. MOV R2,2(R3) ; SET TAIL POINTER TO POINT TO NEW LAST ACB. 13$: MOVB A.PRM+4(R0),R1 ; GET LENGTH OF ACB. CMP -(R0),-(R0) ; BACK UP TO START OF ACB. CALL $DEACB ; DEALLOCATE THE ACB. BR 10$ ; PROCESS NEXT LUN (ONE ACB PER LUN IS ENOUGH). 16$: .ENDC ; C$$RTK .IF DF P$$OFF MOV $TSKHD,R0 ;POINT TO FIRST INSTALLED TASK TCB 20$: TST T.RDCT(R5) ;ANY RUNDOWN OPERATIONS REMAINING? BEQ 60$ ;IF EQ NO MOV T.TCBL(R0),-(SP) ;SAVE POINTER TO NEXT INSTALLED TASK BEQ 30$ ;IF EQ CURRENT TASK IS NULL TASK ADD #T.OCBH,R0 ;POINT TO OCB QUEUE OF TASK 25$: MOV (R0),R0 ;POINT TO NEXT ENTRY IN LIST BEQ 30$ ;IF EQ THERE IS NONE CMP O.PTCB(R0),R5 ;IS EXITING TASK THE PARENT? BNE 25$ ;IF NE NO DEC T.RDCT(R5) ;DECREMENT RUNDOWN COUNT CLR O.PTCB(R0) ;INDICATE PARENT TASK HAS EXITTED .IF DF G$$GEF CMP O.EFN(R0),#64. ;GROUP GLOBAL EVENT FLAG ? BLOS 25$ ;IF LOS NO MOV R0,-(SP) ;SAVE OCB POINTER MOV O.EFN(R0),R0 ;GET EVENT FLAG NUMBER CALL $CEFI ;CONVERT TO MASK AND MASK ADDRESS MOV R1,R3 ;COPY EVENT FLAG MASK ADDRESS CALL $DEAGF ;DEACCESS GROUP GLOBAL EVENT FLAGS MOV (SP)+,R0 ;RESTORE OCB POINTER .ENDC ; DF G$$GEF BR 25$ ;TRY TO REMOVE ANY MORE 30$: MOV (SP)+,R0 ;RESTORE TCB ADDRESS BNE 20$ ;IF NE NO .IF DF V$$TRM MOV $VTDCB,R1 ;POINT TO SECOND VIRTUAL TERMINAL UCB 40$: TST T.RDCT(R5) ;ANY OUTSTANDING CREATED VT: UNITS? BEQ 60$ ;IF EQ NO CMP D.NAM(R1),#"VT ;STILL GOING THROUGH VT UNITS? BEQ 45$ ;IF EQ YES RETURN ;ELSE $ALOCB FAILURE IN $ELMVT - WAIT 45$: MOV (R1),-(SP) ;SAVE ADDRESS OF NEXT DCB MOV D.UCB(R1),R0 ;POINT TO VIRTUAL TERMINAL UCB CMP U.PTCB(R0),R5 ;WAS THIS UNIT CREATED BY EXITING TASK? BNE 50$ ;IF NE NO CALL $ELMVT ;MARK UNIT FOR DEALLOCATION 50$: MOV (SP)+,R1 ;POINT TO NEXT DCB BR 40$ ; .ENDC .ENDC 60$: ADD #T.ST2,R5 ;POINT TO SECOND TASK STATUS WORD BIT #T2.ABO,(R5) ;TASK MARKED FOR ABORT? BEQ 110$ ;IF EQ NO MOV $TKNPT,R0 ;GET TERMINATION NOTIFICATION TCB ADDRESS .IF DF R$$PRO .IIF NDF P$$OFF, .ERROR ;P/OS REQUIRES PARENT OFFSPRING SUPPORT BNE 2000$ ;IF NE TKTN IS IN THE SYSTEM TST T.OCBH-T.ST2(R5);TASK HAVE A PARENT? BNE 110$ ;IF NE YES - OK, GO ON WITH THE EXIT BGCK$A BF.XIT,BE.NPA,FATAL ;A SYSTEM TASK (ONE WITHOUT A PARENT) ;ABORTED WITH NO TKTN - BUGCHECK .IFF ;R$$PRO BEQ 110$ ;IF EQ TKTN IS NOT IN THE SYSTEM .ENDC ;R$$PRO 2000$: CMP $TKTCB,R0 ;TERMINATION NOTIFICATION TASK BEING TERMINATED? BEQ 103$ ;IF EQ YES CMPB #S.CTKN,T.EFLG-T.ST2(R5) ;PREVENT TKTN FROM BEING CALLED? BNE 101$ ;IF NE, NO BIC #T3.MCR!T3.CMD,T.ST3-T.ST2(R5) ;DON'T ISSUE PROMPT OR SNCMD BR 110$ ;CONTINUE PROCESSING 101$: BIS #TS.MSG,-(R5) ;SET ABORT MESSAGE IN PROGRESS CALL $EXRQN ;REQUEST TERMINATION NOTIFICATION TASK CALLR $TKWSE ;WAITFOR SIGNIFICANT EVENT 103$: MOV $ACTHD,R0 ;GET ADDRESS OF FIRST TCB 107$: BIC #TS.MSG,T.STAT(R0) ;CLEAR WAITING FOR MESSAGE BIC #T2.ABO,T.ST2(R0) ;CLEAR MARKED FOR ABORT MOV T.ACTL(R0),R0 ;GET ADDRESS OF NEXT TCB TST T.ACTL(R0) ;NULL TASK? BNE 107$ ;IF NE MORE TO GO 110$: BIS #TS.EXE,-(R5) ;DEACTIVATE TASK BIC #TS.CKR!TS.CIP!TS.MSG!TS.RUN,(R5)+ ; CLEAR STATUS BITS BIC #CLRMSK,(R5)+ ; MOVB T.DPRI-T.ST3(R5),T.PRI-T.ST3(R5) ;RESTORE TASK PRIORITY .IF DF L$$GCL MOV R5,R0 ;GET POINTER TO CURRENT TCB SUB #T.ST3,R0 ;IN R0 MOV #LT.TSK,R1 ;INDICATE THAT DELETING ALL TASK LOGICALS MOV #$LDELX,-(SP) ;JMP TO DELETE ROUTINE IN 4TH DIRCOM CALL $MPDC3 ;MAP THE COMMON AND JMP TO ROUTINE .ENDC MOV T.PCB-T.ST3(R5),R0 ;POINT TO TASK PCB .IF DF M$$PRO CLR T.RRM-T.ST3(R5) ;ASSUME TASK WAS NOT INSTALLLED WITH AFFINITY BIT #T2.AFF,T.ST2-T.ST3(R5) ;WAS TASK INSTALLED WITH AFFINITY? BEQ 115$ ;NO IF EQ MOV P.RRM(R0),T.RRM-T.ST3(R5) ;RESTORE INSTALLED AFFINITY .ENDC 115$: BIT #PS.FXD,P.STAT(R0) ;TASK FIXED IN MEMORY? BNE 130$ ;IF NE YES 120$: BIS #PS.COM,P.STAT(R0) ;CONVERT TASK REGION TO UNNAMED COMMON CLR P.ST2(R0) ; CLR P.NAM(R0) ; CLR P.NAM+2(R0) ; MOV P.MAIN(R0),-(SP) ;SAVE MAIN PCB POINTER MOV R5,-(SP) ;SAVE ADDRESS OF THIRD STATUS WORD 125$: MOV (SP),R5 ;PICK UP ADDRESS OF THIRD STATUS WORD MOV T.ATT-T.ST3(R5),R5 ;POINT TO NEXT ATTACHMENT DESCRIPTOR BEQ 126$ ;IF EQ THERE IS NONE SUB #A.TCBL,R5 ;POINT TO START OF ATTACHMENT DESCRIPTOR MOV A.TCB(R5),R0 ;POINT TO ATTACHED TCB MOV A.PCB(R5),R1 ;POINT TO PCB TSTB A.MPCT(R5) ;IS TASK MAPPED? BEQ 1257$ ;NO IF EQ CLRB P.PRI(R1) ;INITIALIZE REGION PRIORITY MOV R1,R2 ;COPY PCB ADDRESS ADD #P.ATT,R2 ;POINT TO ATTACHMENT LIST 1251$: MOV (R2),R2 ;GET NEXT ATTACHMENT DESCRIPTOR BEQ 1252$ ;IF EQ END OF LIST TSTB A.MPCT-A.PCBL(R2) ;IS TASK MAPPED? BEQ 1251$ ;IF EQ NO MOV A.TCB-A.PCBL(R2),R3 ;GET TCB ADDRESS ADD #T.ST3,R3 ;CALCULATE ADDRESS OF THIRD STATUS WORD CMP R3,(SP) ;SAME AS CURRENT TASK? BEQ 1251$ ;IF EQ YES CMPB T.PRI-T.ST3(R3),P.PRI(R1) ;HIGHER PRIORITY? BLO 1251$ ;IF LO NO MOVB T.PRI-T.ST3(R3),P.PRI(R1) ;SET PRIORITY INCB P.PRI(R1) ;PRIO OF COMMON IS ONE MORE THAN TASK BR 1251$ ;GO AGAIN 1252$: CLRB A.MPCT(R5) ;CLEAR MAPPING COUNT INTO REGION .IF DF M$$PRO CALL $RESBP ;RESET BYPASS AS APPROPRRIATE .ENDC CALL $DEARG ;DEACCESS REGION 1257$: CALL $DETRG ;DETACH THE REGION BR 125$ ; 126$: MOV (SP)+,R5 ;RESTORE ADDRESS OF THIRD STATUS WORD TST T.STAT-T.ST3(R5) ;TASK REACTIVATED DURING $DXXRG ? ;HAPPENS WHEN $NXTSK IS CALLED ;FROM $DXXRG WHEN TKTN EXITS AND ;A CHECKPOINT ALLOCATION FAILURE ;CAUSES TKTN TO RUN AGAIN BPL 127$ ;IF PL YES, DON'T MODIFY T.PCB MOV (SP),T.PCB-T.ST3(R5) ;RESET TASK PCB ADDRESS 127$: TST (SP)+ ;REMOVE PCB ADDRESS FROM STACK BIT #T3.RST,(R5) ;RESTRICTED TASK? BNE 130$ ;IF NE YES, DO NOT DEALLOCATE HEADER .IF DF X$$HDR TSTB T.HDLN-T.ST3(R5) ;RESIDENT TASK HEADER ? BNE 130$ ;IF NE, NO. NOTHING TO DEALLOCATE .ENDC MOV R4,R0 ;SET ADDRESS OF TASK HEADER MOV H.HDLN(R0),R1 ;GET LENGTH OF HEADER IN BYTES CALL $DEACB ;DEALLOCATE HEADER 130$: ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT NUMBER 03. ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- $SPH03==. ;SPM CHANGES THE INSTRUCTION AT ;THE LOCATION OF THIS LABEL MOV @#$TKTCB,R0 ;GET ADDRESS OF CURRENT TCB .IF DF N$$DIR MOV T.CTX(R0),R1 ;GET CONTEXT BLOCK BEQ 133$ ;IF EQ, NO CONTEXT BLOCK CALL $DLCTX ;DEALLOCATE CONTEXT BLOCK CLR T.CTX(R0) ;CLEAR CTX POINTER 133$: ;REFERENCE POINTER .ENDC ; DF N$$DIR .IF DF A$$CNT CLR T.EFLM(R0) ;ASSUME NO TIME LIMIT ON TASK CLR T.EFLM+2(R0) ; TST T.ACN(R0) ;IS THERE AN ACCOUNTING BLOCK BEQ 160$ ;IF EQ NO MOV R0,R4 ;SAVE TCB ADDRESS TSTB $BILNG ;IS CPU TIME CURRENTLY BEING BILLED BNE 135$ ;IF NE NO CALL $CPUTM ;CALCULATE LAST SEGMENT OF CPU TIME USED 135$: MOV T.ACN(R4),R1 ;GET ADDRESS OF ACCOUNTING BLOCK MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV R1,KISAR6 ;MAP ACCOUNTING BLOCK CMPB #BT.TAB,@#B.TYP+140000 ;IS THIS A TAB BNE 140$ ;IF NE NO MOV @#B.PNT+140000,-(SP) ;SAVE POINTER TO UAB MOV @#B.CPUL+140000,T.EFLM(R4) ;PUT TIME LIMIT BACK IN TCB MOV @#B.CPUL+2+140000,T.EFLM+2(R4) ; BITB #BS.TML,@#B.STM+140000 ;IS TAB FOR TIME LIMIT ONLY BEQ 137$ ;IF EQ NO MOV R1,R0 ;GET TAB ADDRESS MOV #B.TBLK,R1 ;SIZE OF TAB CALL $DESEC ;DEALLOCATE TAB BR 138$ ; 137$: MOV T.EFLG+2(R4),@#B.EXST+140000 ;PUT EXIT STATUS IN TAB MOVB T.EFLG(R4),R0 ;GET TKTN ABORT CODE WITH SIGN EXTEND MOV R0,@#B.EXST+2+140000 ;PUT TKTN ABORT CODE IN TAB BICB #BS.ACT,@#B.STM+140000 ;DEACTIVATE TAB CALL $QACNT ;OUTPUT TAB TO SYSLOG 138$: MOV (SP)+,R1 ;POINT TO UAB MOV R1,KISAR6 ;MAP UAB 140$: DEC @#B.ACT+140000 ;DECREMENT ACTIVE TASK COUNT DECB @#B.USE+140000 ;DECREMENT USE COUNT OF UAB BGT 150$ ;IF GT, UAB STILL ACTIVE BICB #BS.ACT,@#B.STM+140000 ;DEACTIVATE UAB CALL $QACNT ;OUTPUT UAB TO SYSLOG 150$: MOV (SP)+,KISAR6 ;RESTORE ORIGINAL MAPPING MOV R4,R0 ;RESTORE TCB ADDRESS CLR T.ACN(R0) ;ZERO ACCOUNTING BLOCK POINTER 160$: .ENDC BIC #T4.CTC,T.ST4-T.ST3(R5) ;CLEAR THE ^C ABORT PROCESSING BIT CALL $ACTRM ;REMOVE TCB FROM THE ATL QUEUE BIT #T3.MCR,(R5) ;MCR EXTERNAL FUNCTION TASK? BEQ 175$ ;IF EQ NO MOV T.UCB-T.ST3(R5),R1 ;GET TI UCB ADDRESS 170$: MOV U.RED(R1),R1 ;FOLLOW REDIRECT CHAIN CMP U.RED(R1),R1 ;IS DEVICE REDIRECTED? BNE 170$ ;IF NE YES BIT #DV.TTY,U.CW1(R1) ;IS IT A TTY DEVICE? BEQ 175$ ;IF EQ NO MOV T.UCB-T.ST3(R5),R2 ;GET UCB ADDRESS MOV #CC.EXT,R1 ;ISSUE TASK EXIT PROMPT BIT #T3.CMD,(R5) ;IS TASK EXECUTING CLI COMMAND BEQ 173$ ;IF EQ NO BIS #CC.TTD,R1 ;FORCE $SNCMD TO BE CALLED LATER 173$: CALL $QCNTP ;ISSUE PROMPT REQUEST TO MCR BR 177$ ; 175$: BIT #T3.CMD,(R5) ;IS TASK EXECUTING CLI COMMAND BEQ 180$ ;IF EQ NO MOV T.UCB-T.ST3(R5),R0 ;GET UCB ADDRESS CALL $SNCMD ;TELL TTDRV TO SEND NEXT COMMAND TO MCR... 177$: BIC #T3.MCR!T3.CMD,(R5) ;CLEAR STATUS BITS 180$: ;REFERENCE LABEL .IF DF P$$OFF MOV R5,R0 ;COPY POINTER TO THIRD STATUS WORD ADD #T.OCBH-T.ST3,R0 ;POINT TO OCB QUEUE LISTHEAD CALL $QRMVF ;REMOVE NEXT OCB BCS 190$ ;IF CS THERE IS NONE MOV T.EFLG+2-T.ST3(R5),R0 ;PICK UP SAVED EXIT STATUS MOVB T.EFLG-T.ST3(R5),R2 ;GET TKTN ABORT CODE CALL $QUEXT ;QUEUE EXIT STATUS TO PARENT BR 180$ ;GO AGAIN 190$: ;REFERENCE LABEL .ENDC .IF DF C$$RTK ;IF REMOTE TASK BIT #F5.RTK,$FMSK5 ;ARE REMOTE TASKS BEING USED BEQ 199$ ;IF EQ NO ; ; SEND TASK TERMINATION REQUST TO REMOTE SYSTEM ; MOV $TKTCB,R5 ;GET CURRENT TASK TCB CMPB T.TKI(R5),$RMTSK ;IS THIS ONE OF THE STATIC TASKS? BLOS 198$ ;IF LOS YES, DON'T TERMINATE CMPB #-1,T.TKI(R5) ;TASK'S AME GONE? BEQ 198$ ;YES, DON'T TRY TERMINATION TSTB T.TKI(R5) ;DID THE AME EVER KNOW ABOUT THIS TASK? BEQ 197$ ;NO, DON'T TERMINATE, BUT DISABLE TASK INDEX MOV #AL$SWS,R0 ;SET FLAG AS SWS MOV #1,R1 ;ONLY NEED ONE 32W BLOCK MOV R2,-(SP) ;SAVE A COUPLE OF REGISTERS MOV R3,-(SP) CALL $CPALO ;ALLOCATE A BLOCK BCC 196$ ;CC = OKAY KEEP GOING ADD #4,SP ;CLR OFF STACK - DONT NEED REG'S JMP TKWSE ;RETRY LATER. 196$: MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV R0,KISAR6 ;MAP REQUEST PACKET MOVB #HT$TKN,H$TYPE+MAP6 ;TYPE IS TASK TERMINATION MOV T.EFLG+2(R5),H$STAT+MAP6 ; GIVE PRIMARY EXIT STATUS MOV T.EFLG(R5),H$STAT+2+MAP6 ; AND SECONDARY STATUS MOV (SP)+,KISAR6 ;RESTORE MAPPING MOV R4,-(SP) MOV R5,-(SP) CPSEN$ #SN$DET,R0,#H$SIZE ;SEND PKT AS DETACHED REQUEST MOV (SP)+,R5 ;RESTORE ALL SAVED REGISTERS MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 197$: MOVB #-1,T.TKI(R5) ;SIGNAL TASK HAS NO AME OR IS DISABLED 198$: ADD #T.ST3,R5 ;RESTORE R5 BACK TO STATUS WORD 199$: .ENDC ;C$$RTK .IF DF V$$TRM&P$$OFF CALL $TICLR ;CLEAR OUT POSSIBLE TI:=VTNN: ASSIGNMENT .ENDC BIT #T3.REM,(R5) ;REMOVE TASK AT EXIT? (T.ST3) BEQ 300$ ;IF EQ NO MOV R5,R0 ;COPY POINTER TO THIRD STATUS WORD SUB #T.ST3,R0 ;POINT TO START OF TCB CALL $REMOV ;REMOVE TASK FROM SYSTEM .IF DF C$$RTK ;IF REMOTE TASK BIT #F5.RTK,$FMSK5 ;ARE REMOTE TASKS BEING USED BEQ 300$ ;IF EQ NO BIT #T4.RIN,T.ST4-T.ST3(R5) ;WAS THIS TASK REMOTLY INSTALLED? BEQ 300$ ;IF EQ NO ; ; SEND REMOVE REQUST TO REMOTE SYSTEM ; MOV #AL$SWS,R0 ;SET FLAG AS SWS MOV #1,R1 ;ONLY NEED ONE 32W BLOCK MOV R2,-(SP) ;SAVE A COUPLE OF REGISTERS MOV R3,-(SP) CALL $CPALO ;ALLOCATE A BLOCK BCC 200$ ;CC = OKAY KEEP GOING ADD #4,SP ;CLR OFF STACK - DONT NEED REG'S JMP TKWSE ;RETRY LATER. 200$: MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV R0,KISAR6 ;MAP REQUEST PACKET MOVB #HT$REM,H$TYPE+MAP6 ;TYPE IS REMOVE MOV T.IID-T.ST3(R5),P$IID+MAP6 ;GET IMAGE INDEX CLR P$IID+2+MAP6 ;CLEAR NEXT WORD MOV (SP)+,KISAR6 ;RESTORE MAPPING MOV R4,-(SP) MOV R5,-(SP) CPSEN$ #SN$DET,R0,#H$SIZE+4 ;SEND PKT AS DETACHED REQUEST MOV (SP)+,R5 ;RESTORE ALL SAVED REGISTERS MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 .ENDC ;C$$RTK 300$: .IF DF X$$HDR CLR $SAHPT ;DO NOT SAVE CONTEXT OF CURRENT TASK .IFF CLR $HEADR ;DO NOT SAVE CONTEXT OF CURRENT TASK .ENDC CLR $TKTCB ;SHOW NO CURRENT TASK .IF DF M$$PRO CLR @$TKPTR ;SAME HERE FOR COMMON TABLE .ENDC CALLR $DRDSE ;DECLARE SIGNIFICANT EVENT ; ; SUBROUTINE TO EMPTY QUEUE ; .IF DF K$$DAS MTQUE: BIC #PMODE,PS ;SET PREVIOUS MODE TO KERNEL FOR PARAMS MFPI (R5)+ ;GET OFFSET TO QUEUE LISTHEAD MOV (SP)+,R4 ; 10$: ;REF LABEL .IFF MTQUE: MOV (R5)+,R4 ;GET OFFSET TO QUEUE LISTHEAD 10$: TST (R5)+ ;ADVANCE TO RETURN ADDRESS .IFTF 13$: MOV (SP),R0 ;PICK UP TCB ADDRESS ADD R4,R0 ;POINT TO QUEUE LISTHEAD CALL $QRMVF ;REMOVE AN ENTRY FROM QUEUE BCS 40$ ;IF CS NO ENTRIES LEFT MOV R1,R0 ;SET ADDRESS OF BLOCK TO DEALLOCATE CMP R4,#T.ASTL ;AST? BNE 20$ ;IF NE NO MOVB 2(R0),R1 ;SET LENGTH OF BLOCK (FOR AST'S ONLY) BGT 20$ ;IF GT LENGTH SPECIFIED (AST'S ONLY) .IF DF,R$$IIC&M$$PRO!C$$RTK ; are kernel ASTs supported BEQ 16$ ; If EQ, do a few more checks ;+ ; In a multiprocessor system it is possible for a task to have ; kernel ASTs queued at the time of task exit. If the exiting task ; goes into the executive lock routine while another task is in ; the process of exiting, an offspring OCB will be queued to the ; task at the exeutive lock. Once the lock is freed, the kernel ; AST will then be dequeued, and the system will crash. ; ; The code included below will resolve this contention ... Ditto ; for CPRSX some executive functions being handled remotely ; ;- MOV R5,-(SP) ; save R5 MOV R4,-(SP) ; and R4 MOV $TKTCB,R5 ; get our current TCB address CALL $DSPKA ; dispatch the kernel AST MOV (SP)+,R4 ; restore R4 MOV (SP)+,R5 ; and R5 BR 13$ ; and process the next packet .IFF ;DF,R$$IIC&M$$PRO!C$$RTK BMI 30$ ; .ENDC ;DF,R$$IIC&M$$PRO!C$$RTK 16$: ; Reference label TST 2(R0) ;IS IT UNSOLICITED CHARACTER AST? BNE 18$ ;IF NE NO IT'S A SPECIFIED AST MOV R4,-(SP) ;SAVE R4 MOV R5,-(SP) ;SAVE R5 CMP -(R0),-(R0) ;POINT TO KISAR5 VALUE OF DEALL SUBR MOV (R0)+,-(SP) ;GET MAPPING OF SUBROUTINE MOV (R0)+,-(SP) ;GET ADDRESS OF DEALLOCATE ROUTINE CALL $MPPRO ;CALL DEALLOCATION ROUTINE MOV (SP)+,R5 ;RESTORE R5 MOV (SP)+,R4 ;RESTORE R4 BR 13$ ;GO AGAIN 18$: MOV #C.LGTH,R1 ;SET SIZE OF BLOCK TO RELEASE CMPB 3(R0),#AS.PEA ;IS THIS A PARITY AST CONTROL BLOCK? BNE 20$ ;IF NE NO MOV #A.PLGH,R1 ;GET LENGTH OF BLOCK 20$: CMP R4,#T.RRFL ;PROCESSING RREF QUEUE? BNE 23$ ;IF NE NO MOV 2(R0),R1 ;GET SENDER'S TCB ADDRESS BEQ 23$ ;IF EQ NO EVENT FLAG RUNDOWN POSSIBLE CMP $TKTCB,R1 ;CHECK IF SENDER IS SELF BEQ 23$ ;IF EQ YES, DEALLOCATE BLOCK MOV #AK.GGF,A.CBL(R0) ;CONVERT TO KERNAL AST CONTROL BLOCK ADD #T.ASTL,R1 ;POINT TO SENDER'S AST QUEUE MOV (R1),(R0) ;ESTABLISH PACKET'S POSITION IN QUEUE BNE 21$ ;IF NE QUEUE WAS NOT EMPTY MOV R0,2(R1) ;ESTABLISH END OF QUEUE 21$: MOV R0,(R1) ;ESTABLISH BEGINNING OF QUEUE BR 13$ ;DEALLOCATE NEXT PACKET 23$: .IFT ;K$$DAS MFPI (R5) ;PUSH DEALLOCATION ROUTINE ADDRESS CALL @(SP)+ ;CALL ROUTINE .IFF ;K$$DAS CALL @-(R5) ;DEALLOCATE CORE BLOCK .IFTF ;K$$DAS BR 10$ ;GO AGAIN 30$: ;REFERENCE LABEL BGCK$A BF.XIT,BE.SGN,FATAL ;NO KERNEL ASTS SHOULD EXIST NOW 40$: ;REF LABEL .IFT TST (R5)+ ;ADVANCE R5 TO EQUAL RETURN ADDRESS BIS #PMODE,PS ;RESTORE PREVIOUS MODE TO USER .ENDC RTS R5 ;RETURN TO CALLER ; ; EMPTY THE RECEIVE LIST. ; IN A SYSTEM SUPPORTING SECONDARY POOL, THE RECEIVE LIST ; CONTAINS DATA PACKETS ALLOCATED FROM THE SECONDARY POOL. ; .IF DF P$$OOL MTRCVL: MOV KISAR6,-(SP) ;SAVE KERNEL MAPPING REGISTER 5 MOV R5,R4 ;COPY TCB ADDRESS ADD #T.RCVL,R4 ;POINT TO RECEIVE LIST 10$: MOV R4,R0 ;GET LIST HEAD ADDRESS CALL $QSPRF ;REMOVE THE NEXT PACKET FROM THE LIST BCS 100$ ;IF CS DONE .IF DF V$$TRM MOV R1,-(SP) ;SAVE PACKET ADDRESS BIAS MOV R1,KISAR6 ;MAP PACKET MOV @#140002,-(SP) ;GET SIZE OF PACKET BIT #T3.SLV,T.ST3(R5) ;IS THIS A SLAVE TASK? BEQ 50$ ;IF EQ NO RUN DOWN NECESSARY MOV (SP),R1 ;CALCULATE ADDRESS OF UCB IN PKT ASL R1 ;CONVERT OFFSET TO BYTES MOV 140004(R1),R0 ;GET UCB ADDRESS IN PKT MOV @R0,R1 ;GET DCB ADDRESS CMP D.NAM(R1),#"VT ;IS THIS A VT? BNE 50$ ;IF NE NO DECB U.OCNT(R0) ;DECREMENT VT OFFSPRING COUNT BNE 50$ ;IF NE THERE'S MORE OFFSPRING TST U.PTCB(R0) ;HAS THE PARENT GONE AWAY? BNE 50$ ;IF NE NO .IF DF D$$PAR .IF NDF K$$DAS MOV 4(SP),KISAR6 ;REMAP APR6 TO ORIGINAL MAPPING ;WHICH MUST SHARE KISAR5 .ENDC .ENDC CALL $DEAVT ;DEALLOCATE VT DATA STRUCTURES 50$: MOV (SP)+,R1 ;RESTORE PACKET SIZE MOV (SP)+,R0 ;RESTORE ADDRESS BIAS OF PACKET .IF DF D$$PAR .IF NDF K$$DAS MOV R0,KISAR6 ;REMAP PACKET .ENDC .ENDC .IFF MOV R1,R0 ;COPY PACKET ADDRESS FOR DEALLOC ROUTINE MOV R1,KISAR6 ;MAP TO THE PACKET THROUGH APR5 MOV @#140002,R1 ;CALCULATE PACKET SIZE .ENDC ;V$$TRM .IF DF N$$DIR BIT #T3.SLV,T.ST3(R5) ;IS RECEIVER A SLAVE TASK? BEQ 80$ ;IF EQ, NO - NO CONTEXT BLOCK PTR MOV R1,-(SP) ;SAVE SIZE ASL R1 ;CONVERT TO BYTES MOV 140014(R1),R1 ;GET CONTEXT BLOCK POINTER BEQ 70$ ;IF EQ, NONE CALL $DLCTX ;DELETE CONTEXT BLOCK 70$: MOV (SP)+,R1 ;RESTORE SIZE 80$: ADD #<7.+37>,R1 ;INCLUDE CONTROL WORDS .IFF ADD #<6.+37>,R1 ;INCLUDE CONTROL WORDS .ENDC ;DF N$$DIR ASH #-5,R1 ;CONVERT TO 32. WORD UNITS CALL $DESEC ;DEALLOCATE THE PACKET BR 10$ ;GO AGAIN 100$: MOV (SP)+,KISAR6 ;RESTORE MAPPING REGISTER 5 RETURN ; .ENDC ; ; CO-ROUTINE TO SCAN LOGICAL UNIT TABLE ; SCNLN: MOV (SP),R3 ;SAVE RETURN ADDRESS CLR (SP) ;START AT LUN ZERO 10$: MOV $TKTCB,R5 ;GET ADDRESS OF CURRENT TASK TCB .IF DF X$$HDR MOV $SAHPT,R4 ;GET CURRENT TASK HEADER MOV $SAHDB,KISAR6 ;MAP IT .IFF MOV $HEADR,R4 ;GET CURRENT TASK HEADER .ENDC 20$: MOV (SP),R1 ;GET NEXT LUN NUMBER INC (SP) ;INCREMENT LUN NUMBER CMP H.NLUN(R4),(SP) ;END OF LUT? BLO 30$ ;IF LO YES CALL $MPLNE ;MAP LUN NUMBER TO UCB ADDRESS BCS 20$ ;IF CS NO DEVICE ASSIGNED TO LUN BIT #DV.ISP!DV.OSP,U.CW1(R2) ;SPOOLED DEVICE? BEQ 25$ ;IF EQ NO CMP U.ATT(R2),R5 ;SPOOLER TASK EXIT? BEQ 25$ ;IF EQ YES MOV R0,R2 ;ELSE USE INTERMEDIATE DEVICE UCB CLC ;INSURE C - CLEAR FOR RETURN 25$: MOV R2,R5 ;SET UCB ADDRESS FOR RETURN CALL (R3) ;CALL THE CALLER BACK MOV (SP)+,R3 ;RETRIEVE RETURN ADDRESS BR 10$ ;GO AGAIN 30$: MOV R3,(SP) ;SET RETURN ADDRESS RETURN ; ;+ ; ** - LTPRE - CALL LAT PROCESS FOR EXIT NOTIFICATION ; ; THIS ROUTINE NOTIFIES THE LAT PROCESS WHEN AN EXITING TASK HAS A LUN ; ASSIGNED TO A LAT APPLICATIONS TERMINAL SO THAT A DISCONNECT MAY BE PERFORMED ; ; INPUTS: ; R5 = UCB ADDRESS ; ; OUTPUTS: ; LAT PROCESS NOTIFIED IF NECESSARY. ;- .IF DF M$$NET&T$$LTH LTPRE: MOV U.DCB(R5),R0 ;GET DCB ADDRESS CMP #"TT,D.NAM(R0) ;IS IT A TT TERMINAL? BNE 10$ ;IF NE NO BIT #S6.LAT,U.TST6(R5) ;LAT APPLICATION TERMINAL? BEQ 10$ ;IF EQ NO MOV U.SCB(R5),R4 ;R4-SCB ADDRESS MOV S.KRB+2(R4),-(SP) ;BIAS MOV $LTEEP,-(SP) ;VIRT ADDR = LAT PROC EXIT ;ENTRY POINT CALL $MPPRO ;MAPS AND CALLS LAT PROCESS ;RESTORES SP 10$: RETURN .ENDC ; DF M$$NET&T$$LTH ;+ ; **-$RLMCB-RELEASE COMMAND BUFFERS QUEUED FOR A TASK ; ; INPUTS: ; ; R5=ADDRESS OF TCB OF THE TASK WHOSE BUFFERS SHOULD BE DELETED ; ; OUTPUTS: ; ; ALL COMMAND LINES FOR THE TASK ARE RELEASED ; ;- $RLMCB::MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING 10$: CALL $SCMDQ ;FIND A COMMAND FOR THIS TASK BCS 30$ ;IF CS, NO MORE MOV R0,R1 ;COPY ADDRESS MOV #$CLICQ,R0 ;POINT TO LISTHEAD CALL $GTSPK ;UNLINK IT MOV R1,KISAR6 ;MAP BLOCK BIT #CC.TTD,@#C.CSTS+140000 ;DID COMMAND ORIGINATE IN TTDRV BEQ 20$ ;IF EQ NO MOV @#C.CUCB+140000,R0 ;GET UCB ADDRESS CALL $SNCMD ;TELL TTDRV TO SEND NEXT COMMAND 20$: MOV KISAR6,R0 ;GET ADDRESS MOVB C.CBLK+140000,R1 ;GET LENGTH CALL $DESEC ;DEALLOCATE IT BR 10$ ;CHECK FOR ANY MORE 30$: MOV (SP)+,KISAR6 ;RESTORE MAPPING DUN: RETURN .END